﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using GmailMetroNotifier.Client.Common;
using GmailMetroNotifier.Client.Properties;
using Windows.Data.Xml.Dom;
using Windows.Foundation;
using Windows.UI.Notifications;

namespace GmailMetroNotifier.Client.UIP
{
    /// <summary>
    /// Implements an <see cref="INotificationProvider"/> that leverages Windows 8 toast notifications.
    /// </summary>
    public class ToastNotificationProvider : INotificationProvider
    {
        /// <summary>
        /// Delivers a notification using the indicated severity and message.
        /// </summary>
        /// <param name="message">The message to notify.</param>
        /// <param name="severity">The severity of the notification.</param>
        /// <returns>The result of the notification.</returns>
        public void Notify(string message, NotificationSeverity severity)
        {
            this.Notify(message, severity, null);
        }

        /// <summary>
        /// Delivers a notification using the indicated severity and message.
        /// </summary>
        /// <param name="message">The message to notify.</param>
        /// <param name="severity">The severity of the notification.</param>
        /// <param name="handler">The action to be called for handling the notification result.</param>
        /// <returns>The result of the notification.</returns>
        public void Notify(string message, NotificationSeverity severity, Action<NotificationResult> handler)
        {
            if (message == null)
            {
                throw new ArgumentNullException("message");
            }

            if (message.Trim().Length == 0)
            {
                throw new ArgumentException(Resources.EXCEPTION_MSG_ARGUMENT_EXCEPTION, "message");
            }

            XmlDocument toastNotificationXml = GetToastNotificationXml(message);

            ToastNotification toastNotification = new ToastNotification(toastNotificationXml);

            toastNotification.Activated += new WeakEventHandler<ToastNotification, object>((sender, args) =>
                {
                    handler(NotificationResult.OK);
                }).Handler;

            toastNotification.Dismissed += new WeakEventHandler<ToastNotification, object>((sender, args) =>
                {
                    handler(NotificationResult.Cancel);
                }).Handler;

            toastNotification.Failed += new WeakEventHandler<ToastNotification, object>((sender, args) =>
                {
                    handler(NotificationResult.Cancel);
                }).Handler;

            ToastNotificationManager.CreateToastNotifier(Constants.ApplicationId).Show(toastNotification);
        }

        private static XmlDocument GetToastNotificationXml(string message)
        {
            XmlDocument toastNotificationXml =
                ToastNotificationManager.GetTemplateContent(ToastTemplateType.ToastText01);

            // Set the text of the toast notification
            XmlElement textElement = (XmlElement)toastNotificationXml.SelectSingleNode("//text");

            XmlText toastText = toastNotificationXml.CreateTextNode(message);

            textElement.AppendChild(toastText);

            XmlElement audioNode = toastNotificationXml.CreateElement("audio");
            audioNode.SetAttribute("src", Constants.ToastSound);

            toastNotificationXml.DocumentElement.AppendChild(audioNode);

            return toastNotificationXml;
        }
    }
}
